#ifndef NETCLIENT_H
#define NETCLIENT_H

#include <QObject>
#include <QProtobufSerializer>
#include <QNetworkReply>
#include <QNetworkAccessManager>

namespace model {
class SearchLimits;
class InterviewInfo;
class DataCenter;
}

namespace network {

class NetClient : public QObject
{
    Q_OBJECT
private:
    const QString HTTP_URL = "http://127.0.0.1:8000/";

public:
    NetClient() {}

    void ping();

    void searchInterview(const model::SearchLimits &limits);

    void searchQuestionCluster(const model::SearchLimits &limits);

    void searchCompany(const model::SearchLimits &limits);

    void uploadInterview(const model::InterviewInfo &interview);

private:
    QString makeRequestId() const;

    QNetworkReply *sendHttpRequest(const QString &path, const QByteArray &body);

    template <typename T>
    std::shared_ptr<T> getHttpResponse(QNetworkReply* rsp, bool* ok, QString* errmsg);

signals:

private:
    QNetworkAccessManager _httpClient;

    QProtobufSerializer _serializer;
};

template<class PbObj>
std::shared_ptr<PbObj> NetClient::getHttpResponse(QNetworkReply* rsp, bool* ok, QString* errmsg)
{
    if (rsp->error() != QNetworkReply::NoError) {
        *ok = false;
        *errmsg = rsp->errorString();
        rsp->deleteLater();
        return std::make_shared<PbObj>();
    }

    QByteArray data = rsp->readAll();

    auto pbRsp = std::make_shared<PbObj>();
    pbRsp->deserialize(&_serializer, data);

    if (pbRsp->success() == false) {
        *ok = false;
        *errmsg = pbRsp->errmsg();
        rsp->deleteLater();
        return std::make_shared<PbObj>();
    }

    *ok = true;
    rsp->deleteLater();
    return pbRsp;
}

} // namespace network
#endif // NETCLIENT_H
